package com.i2863.shiroDemo.config;

import com.google.code.kaptcha.Constants;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author cexy
 * @date 2021/5/17 10:41
 * @description  shiro登录自定义验证码校验过滤器
 **/
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        // 在这里进行验证码的校验  
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpSession session = httpServletRequest.getSession();

        // 取出验证码  
        String validateCode = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        // 取出页面的验证码  
        // 输入的验证和session中的验证进行对比  
        String code = httpServletRequest.getParameter("code");
        String token = httpServletRequest.getHeader(Constant.HEADER_TOKEN_NAME);

        //app端 token校验
        String path = httpServletRequest.getServletPath();
        if (path.contains(Constant.APP_PATH_PREFIX) && !path.contains(Constant.APP_PATH_PREFIX + "login")) {
            if (StringUtils.isEmpty(token)) {
                HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
                httpServletResponse.sendError(Constant.LOGIN_EXPIRED, "未授权登录!");
                return false;
            }
        }

        //app端登录入口
        if (code == null && pathsMatch(Constant.APP_PATH_PREFIX + "login", httpServletRequest)) {
            if (isLoginSubmission(request, response)) {
                return executeLogin(request, response);
            } else {
                //allow them to see the login page ;)
                return true;
            }
        }
        //app端登录失效
        if (code == null && token != null) {
            HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
            httpServletResponse.sendError(Constant.LOGIN_EXPIRED, "登录失效!");
            return false;
        }
        //web端验证code
        if (code != null && validateCode != null && !code.equalsIgnoreCase(validateCode)) {
            // 如果校验失败，将验证码错误失败信息，通过shiroLoginFailure设置到request中  //自定义登录异常
            httpServletRequest.setAttribute("shiroLoginFailure", "kaptchaValidateFailed");
            // 拒绝访问，不再校验账号和密码  
            return true;
        }
        return super.onAccessDenied(request, response);
    }

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
                                     ServletRequest request, ServletResponse response) throws Exception {
        String code = request.getParameter("code");
        if (code == null) {
            return true;
        } else {
            issueSuccessRedirect(request, response);
        }
        //we handled the success redirect directly, prevent the chain from continuing:
        return false;
    }
}